<?php
/**
 * #Celebrate Shieh
 *             ,%%%%%%%%,
 *           ,%%/\%%%%/\%%
 *          ,%%%\c "" J/%%%
 * %.       %%%%/ o  o \%%%
 * `%%.     %%%%    _  |%%%
 *  `%%     `%%%%(__Y__)%%'
 *  //       ;%%%%`\-/%%%'
 * ((       /  `%%%%%%%'
 *  \\    .'          |
 *   \\  /       \  | |
 *    \\/         ) | |
 *     \         /_ | |__
 *     (___________))))))) 攻城湿
 *
 *        _       _
 * __   _(_)_   _(_) __ _ _ __
 * \ \ / / \ \ / / |/ _` |'_ \
 *  \ V /| |\ V /| | (_| | | | |
 *   \_/ |_| \_/ |_|\__,_|_| |_|
 */

namespace App\Modules\Blog\Service;


use App\Models\Blog\Notice;
use App\Models\Common\Invitation;
use App\Models\System\Info;
use App\Models\System\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Ofcold\IdentityCard\IdentityCard;

class UserService
{

    use Service;

    /**
     * 获取二维码
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function LoginWxQrCodeService()
    {
        $image = 'qrCode/wx/wxQrCode.png';
        $disk  = $this->getStorage();
        if ( $disk->exists($image) ) return data($disk->url($image));
        $disk->makeDirectory('qrCode/wx');
        $qrCode = storage_path('app/public/' . $image);
        $this->getPreview()->createQrCode(200, $qrCode, '项目正在快马加鞭');
        return data($disk->url($image));
    }

    /**
     * 登陆
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function LoginStoreService( $request )
    {
        $error         = $this->getErrorCode();
        $blogValidator = $this->getBlogValidator();

        if ( $this->getCommon()->UserCommonService() ) return message($error::message(102), 102);
        $redis  = $this->getRedisLibs();
        $select = [ 'id', 'static', 'password', 'status' ];
        $result = DB::transaction(function () use ( $request, $redis, $blogValidator, $select, $error ) {
            switch ( $request->input('static', 'login') ) {
                case'login':
                    $username = $request->input('username');
                    $codeKey  = 'blog:login:prohibit:' . $username;
                    if ( $redis->exists($codeKey) ) if ( $redis->get($codeKey) >= (int) config('blog_page.LOGIN_PROHIBIT') ) return message('您失败次数太多，请稍后重试：' . secToTime($redis->ttl($codeKey), 'd'));//发送短信次数从配置读取
                    $validator = $blogValidator->BlogLoginValidator($request);//验证字段
                    if ( ! $validator ) return message($error::message(1001));
                    if ( $validator->first() ) return message($validator->first());
                    $where = function ( $query ) use ( $username ) {
                        $query->where('is_show', 2);
                        $query->where(function ( $query ) use ( $username ) {
                            $query->where('name', $username)->orWhere('email', $username)->orWhere('phone', $username);
                        });
                        $query->where('status', 1);
                    };
                    if ( ! $user = User::FirstModel($where, [], $select) ) return message($error::message(2204));//查询此用户
                    switch ( $user->static ) {
                        case 2:
                            return message($error::message(2205));
                            break;
                    }
                    if ( ! Hash::check($request->input('password'), $user->getAuthPassword()) ) {
                        $redis->incr($codeKey);//增加redis 值
                        $redis->expire($codeKey, (int) config('blog_page.SECONDS_PROHIBIT'));//设置过期时间
                        return message($error::message(2206));
                    }
                    $data = [
                        'access_token' => \Auth::guard('api')->setTTL(config('blog_page.JWT_TIME'))->fromUser($user),
                        //把用户给JWT过期时间从配置取
                        'expires_in'   => \Auth::guard('api')->factory()->getTTL(),
                        //获取过期时间
                    ];
                    $user->info()->increment('frequency');//增加登录次数
                    break;
                case 'code':
                    $validator = $blogValidator->BlogCodeValidator($request);//验证字段
                    if ( ! $validator ) return message($error::message(1001));
                    if ( $validator->first() ) return message($validator->first());
                    if ( ! $request->filled('code') ) return message($error::message(1004));
                    $email = $request->input('email');
                    $key   = 'blog:login:code:' . $email;
                    $code  = $redis->get($key);
                    if ( ! $code ) return message($error::message(1030));
                    $code = json_decode($code, TRUE);
                    if ( $code[ 'code' ] != $request->input('code') ) return message($error::message(1021));
                    $where = function ( $query ) use ( $email ) {
                        $query->where('is_show', 2);
                        $query->where('email', $email);
                    };
                    if ( ! $user = User::FirstModel($where, [], $select) ) {
                        $code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);//随机数
                        $user = User::CreateModel([
                            'email'    => $email,
                            'name'     => config('blog_page.USER_USERNAME') . '_' . $code,//账号前缀从配置取 加随机数
                            'password' => bcrypt(123456),//加密,
                            'static'   => 1,
                            'status'   => 1,
                            'is_show'  => 2,
                        ]);//增加用户
                        Info::CreateModel([ 'uid' => $user->id ]);
                        $data1[ 'user_id' ]   = $user->id;
                        $data1[ 'p_user_id' ] = 0;
                        if ( $request->filled('user_id') ) if ( User::ExistsModel([ 'id' => $request->input('user_id') ]) ) $data1[ 'p_user_id' ] = $request->input('user_id');
                        Invitation::CreateModel($data1);
                        $notice = Notice::PluckModel([ 'is_show' => 1, 'status' => 1 ])->toArray();
                        $user->notice()->sync($notice);
                    }
                    switch ( $user->static ) {
                        case 2:
                            return message($error::message(2205));
                            break;
                    }
                    switch ( $user->status ) {
                        case 2:
                            return message($this->getErrorCode()::message(2222));
                            break;
                        case 3:
                            return message($this->getErrorCode()::message(2222));
                            break;
                    }
                    $data = [
                        'access_token' => \Auth::guard('api')->setTTL(config('blog_page.JWT_TIME'))->fromUser($user),
                        //把用户给JWT过期时间从配置取
                        'expires_in'   => \Auth::guard('api')->factory()->getTTL(),
                        //获取过期时间
                    ];
                    $user->info()->increment('frequency');//增加登录次数

                    break;
                default:
                    return message($error::message(1001));
                    break;
            }
            return data($data, '登录成功');
        });
        return $result;
    }

    /**
     * 退出登陆
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function UserLogoutService()
    {
        \JWTAuth::invalidate(\JWTAuth::getToken());
        return data(NULL, $this->getErrorCode()::message(103));
    }

    /**
     * 获取用户信息
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function UserService( $request )
    {
        if ( ! $user = $this->getCommon()->UserCommonService() ) return message($this->getErrorCode()::message(101), 101);
        $user->info;
        $user->info->file;
        unset($user->password, $user->email_verified_at);
        return data($user);
    }

    /**
     * 修改密码
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function UserPasswordService( $request )
    {
        if ( ! $user = $this->getCommon()->UserCommonService() ) return message($this->getErrorCode()::message(101), 101);
        $validator = $this->getAdminValidator()->ModifyStorePasswordValidator($request);
        if ( $validator->first() ) return message($validator->first());
        $user->password = bcrypt($request->input('password'));
        $user->save();
        return data();
    }

    /**
     * 修改用户信息
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function UserInfoService( $request )
    {
        $error         = $this->getErrorCode();
        $blogValidator = $this->getBlogValidator();
        if ( ! $user = $this->getCommon()->UserCommonService() ) return message($error::message(101), 101);
        if ( $request->input('email') != $user->email ) {
            $validator = $blogValidator->BlogCodeValidator($request);
            if ( $validator->first() ) return message($validator->first());
            $key  = 'blog:email:code:' . $request->input('email');
            $code = $this->getRedisLibs()->get($key);
            if ( ! $code ) return message($error::message(1030));
            $code = json_decode($code, TRUE);
            if ( $code[ 'code' ] != $request->input('code') ) return message($error::message(1021));
        }
        if ( $request->filled('phone') ) {
            request()->offsetSet('user_id', $user->id);
            $validator = $blogValidator->BlogPhoneValidator($request);
            if ( $validator->first() ) return message($validator->first());
        }
        if ( $request->filled('card') ) {
            $idCard = IdentityCard::make($request->input('card'));
            if ( ! $idCard ) return message($error::message(2193));
            request()->offsetSet('birthday', $idCard->getBirthday());
            request()->offsetSet('zodiac', $idCard->getZodiac());
            request()->offsetSet('constellation', $idCard->getConstellation());
        }
        if ( $request->filled('birthday') ) {
            $birthday = new Carbon($request->input('birthday'));
            request()->offsetSet('year', $birthday->year);
            request()->offsetSet('month', $birthday->month);
            request()->offsetSet('day', $birthday->day);
        }
        $user->email               = $request->input('email');
        $user->phone               = $request->input('phone');
        $user->info->rename        = $request->input('rename');
        $user->info->username      = $request->input('username');
        $user->info->card          = $request->input('card');
        $user->info->content       = $request->input('content');
        $user->info->avatar        = $request->input('avatar');
        $user->info->province      = $request->input('province');
        $user->info->city          = $request->input('city');
        $user->info->area          = $request->input('area');
        $user->info->birthday      = $request->input('birthday');
        $user->info->year          = $request->input('year');
        $user->info->month         = $request->input('month');
        $user->info->day           = $request->input('day');
        $user->info->zodiac        = $request->input('zodiac');
        $user->info->constellation = $request->input('constellation');
        $user->info->sex           = $request->input('sex', 1);
        DB::transaction(function () use ( $user, $error ) {
            $user->save();
            $user->info->save();
        });
        return data(NULL, $error::message(210));
    }
}
